/*
 * Jenny Ruppen 09-730-391
 * Sebastien Goldberg 08-914-855
 * Henry Raymond 08-928-061
 * Stefan Mussato 09-752-270
 */
 
package ch.uzh.ifi.sopra.gruppe9.game;


import com.jme3.material.Material;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;


/**
 * Draws a tower element to the screen in 2D or in 3D.
 */
public class GuiTowerElement implements IUpdatable {
	
	
	/**
	 * X coordinates of corners of regular hexagon with diameter 1 clockwise from the right.
	 */
	private static final float[] hexagonX = {0.5f, 0.25f, -0.25f, -0.5f, -0.25f, 0.25f, 0.5f};
	
	
	/**
	 * Y coordinates of corners of regular hexagon with diameter 1 clockwise from the right.
	 */
	private static final float[] hexagonZ = {0.0f, 0.433f, 0.433f, 0.0f, -0.433f, -0.433f, 0.0f};
	
	
	/**
	 * Ratio between pixel coordinates and relative coordinates of the tower texture.
	 */
	private static final float texRatio = 1.0f / 600.0f;
	
	
	/**
	 * Scaling of z coordinates of the model in the 2D representation.
	 */
	private static final float zScale = -0.33333f;
	
	
	/**
	 * Corresponding tower element.
	 */
	private TowerElement towerElement;
	
	
	/**
	 * Offset of the 2D coordinate system of this tower element.
	 */
	private GUI.Offset offset;
	
	
	/**
	 * 2D position of the tower element in the x axis. (Assuming the window has a width of 1024 pixel.)
	 */
	private int positionX;
	
	
	/**
	 * 2D position of the tower element in the y axis. (Assuming the window has a height of 768 pixel.)
	 */
	private int positionY;
	
	
	/**
	 * Z-Index of the 2D element. An element with a higher index will cover an element with a lower one.
	 */
	private int zIndex;
	
	
	/**
	 * Timer for animation. 
	 */
	private float timer = 0.0f;
	
	
	/**
	 * Geometry node of the 2D tower element.
	 */
	private Node towerElement2D;
	
	
	/**
	 * 3D position of the tower element.
	 */
	private Vector3f position3D;
	
	
	/**
	 * Geometry node of the 3D tower element.
	 */
	private Node towerElement3D;
	
	
	/**
	 * Constructor: Loads tower element object
	 */
	public GuiTowerElement(TowerElement towerElement) {
		this.towerElement = towerElement;
	}
	
	
	/**
	 * Position and return 2D object of the tower element.
	 */
	public Node get2D(GUI.Offset offset, int positionX, int positionY, int zIndex, float scale) {
		this.offset = offset;
		this.positionX = positionX;
		this.positionY = positionY;
		this.zIndex = zIndex;
		
		towerElement2D = getGeometry(false);
		towerElement2D.setLocalTranslation(GUI.calculateX(offset, positionX), GUI.calculateY(offset, positionY), zIndex);
		towerElement2D.setLocalScale(scale * GUI.getPixelScale());
		
		return towerElement2D;
	}
		
		
	/**
	 * Position and return 3D object of the tower element.
	 */
	public Node get3D(float positionX, float positionY, float positionZ) {
		this.position3D = new Vector3f(positionX, positionY, positionZ);
		
		towerElement3D = getGeometry(true);
		towerElement3D.setLocalTranslation(position3D);
		towerElement3D.setLocalScale(1.0f);

		return towerElement3D;
	}
	
	
	/**
	 * Create geometry of the tower element
	 */
	private Node getGeometry(boolean in3d) {
		
		Node geometry = new Node();
		
		Material material = null;
		
		if(towerElement.getMaterial() == TowerElement.Material.BROWN) {
			material = MaterialManager.getBrownTower();
		} else if(towerElement.getMaterial() == TowerElement.Material.GREEN) {
			material = MaterialManager.getGreenTower();
		} else if(towerElement.getMaterial() == TowerElement.Material.RED) {
			material = MaterialManager.getRedTower();
		} else if(towerElement.getMaterial() == TowerElement.Material.BLACK) {
			material = MaterialManager.getBlackTower();
		} else if(towerElement.getMaterial() == TowerElement.Material.WHITE) {
			material = MaterialManager.getWhiteTower();
		}
		
		int goldenOffset = 0;
		
		if(towerElement.isGolden()) {
			goldenOffset = 300;
		}
		
		if(towerElement.getType() == TowerElement.Type.BASE) {
			
			Geometry baseWalls = createCylinder(
				48.0f, 40.0f, 25.0f, // Dimensions
				material, // Texture
				246 + goldenOffset, 150 + goldenOffset, 54 + goldenOffset, 320, // Texture position
				96, 80, 100, // Texture dimensions
				in3d); // in 2D
			baseWalls.setLocalTranslation(0.0f, 0.0f, 0.1f);
			geometry.attachChild(baseWalls);
			
			Geometry baseCeiling = createDisc(
				40.0f, // Dimensions
				material, // Texture
				150, 520, // Texture position
				160, // Texture dimensions
				in3d); // in 2D		
			baseCeiling.setLocalTranslation(0.0f, 25.0f, 0.0f);
			geometry.attachChild(baseCeiling);
			
				
		} else if(towerElement.getType() == TowerElement.Type.MIDDLE) {
			
			Geometry middleWalls = createCylinder(
				40.0f, 40.0f, 15.0f, // Dimensions
				material, // Texture
				246 + goldenOffset, 150 + goldenOffset, 54 + goldenOffset, 160, // Texture position
				80, 80, 60, // Texture dimensions
				in3d); // in 2D
			middleWalls.setLocalTranslation(0.0f, 0.0f, 0.1f);
			geometry.attachChild(middleWalls);
				
			Geometry middleCeiling = createDisc(
				40.0f, // Dimensions
				material, // Texture
				150, 520, // Texture position
				160, // Texture dimensions
				in3d); // in 2D		
			middleCeiling.setLocalTranslation(0.0f, 15.0f, 0.0f);
			geometry.attachChild(middleCeiling);
			
				
		} else if(towerElement.getType() == TowerElement.Type.WINDOW) {
			
			Geometry windowWalls = createCylinder(
				40.0f, 40.0f, 25.0f, // Dimensions
				material, // Texture
				246 + goldenOffset, 150 + goldenOffset, 54 + goldenOffset, 220, // Texture position
				80, 80, 100, // Texture dimensions
				in3d); // in 2D
			windowWalls.setLocalTranslation(0.0f, 0.0f, 0.1f);
			geometry.attachChild(windowWalls);
				
			Geometry windowCeiling = createDisc(
				40.0f, // Dimensions
				material, // Texture
				150, 520, // Texture position
				160, // Texture dimensions
				in3d); // in 2D		
			windowCeiling.setLocalTranslation(0.0f, 25.0f, 0.0f);
			geometry.attachChild(windowCeiling);
			
			Geometry windowFloor = createDisc(
				46.0f, // Dimensions
				material, // Texture
				150, 520, // Texture position
				160, // Texture dimensions
				in3d); // in 2D		
			windowFloor.setLocalTranslation(0.0f, 0.0f, 0.0f);
			geometry.attachChild(windowFloor);
			
			Geometry frontBalustrade = createCylinder(
				46.0f, 46.0f, 7.0f, // Dimensions
				material, // Texture
				246, 150, 54, 420, // Texture position
				96, 96, 20, // Texture dimensions
				in3d); // in 2D
			frontBalustrade.setLocalTranslation(0.0f, 0.0f, 0.2f);
			geometry.attachChild(frontBalustrade);
			
			Geometry backBalustrade = createCylinder(
				-46.0f, -46.0f, 7.0f, // Dimensions (Negative so that the balustrade appears behind the tower.
				material, // Texture
				246, 150, 54, 420, // Texture position
				96, 96, 20, // Texture dimensions
				in3d, true); // in 2D and flip surfaces
			backBalustrade.setLocalTranslation(0.0f, 0.0f, -0.2f);
			geometry.attachChild(backBalustrade);
			
		} else if(towerElement.getType() == TowerElement.Type.ROOF) {
			
			if(towerElement.getMaterial() == TowerElement.Material.BROWN) {
				
				Geometry brownRoofWalls = createCylinder(
					40.0f, 40.0f, 10.0f, // Dimensions
					material, // Texture
					246, 150, 54, 120, // Texture position
					80, 80, 40, // Texture dimensions
					in3d); // in 2D
				brownRoofWalls.setLocalTranslation(0.0f, 0.0f, 0.1f);
				geometry.attachChild(brownRoofWalls);
				
				Geometry brownRoofPoint = createCone(
					40.0f, 20.0f, // Dimensions
					material, // Texture
					246, 150, 54, 0, // Texture position
					80, 120, // Texture dimensions
					in3d); // in 2D		
				brownRoofPoint.setLocalTranslation(0.0f, 10.0f, 0.0f);
				geometry.attachChild(brownRoofPoint);
				

			} else if(towerElement.getMaterial() == TowerElement.Material.GREEN) {
				
				Geometry greenRoofWalls = createCylinder(
					40.0f, 40.0f, 5.0f, // Dimensions
					material, // Texture
					246, 150, 54, 140, // Texture position
					80, 80, 20, // Texture dimensions
					in3d); // in 2D
				greenRoofWalls.setLocalTranslation(0.0f, 0.0f, 0.2f);
				geometry.attachChild(greenRoofWalls);
				
				Geometry greenFrontRoofFloor = createCylinder(
					40.0f, 20.0f, 0.0f, // Dimensions
					material, // Texture
					246, 150, 54, 120, // Texture position
					80, 40, 20, // Texture dimensions
					in3d); // in 2D
				greenFrontRoofFloor.setLocalTranslation(0.0f, 5.0f, 0.1f);
				geometry.attachChild(greenFrontRoofFloor);
					
				Geometry greenBackRoofFloor = createCylinder(
					-40.0f, -20.0f, 0.0f, // Dimensions
					material, // Texture
					246, 150, 54, 120, // Texture position
					80, 40, 20, // Texture dimensions
					in3d); // in 2D
				greenBackRoofFloor.setLocalTranslation(0.0f, 5.0f, -0.1f);
				geometry.attachChild(greenBackRoofFloor);
				
				Geometry greenRoofStatue = createCylinder(
					20.0f, 20.0f, 20.0f, // Dimensions
					material, // Texture
					246, 150, 54, 40, // Texture position
					40, 40, 80, // Texture dimensions
					in3d); // in 2D
				greenRoofStatue.setLocalTranslation(0.0f, 5.0f, 0.1f);
				geometry.attachChild(greenRoofStatue);
					
				Geometry greenRoofPoint = createCone(
					20.0f, 10.0f, // Dimensions
					material, // Texture
					246, 150, 54, 0, // Texture position
					40, 40, // Texture dimensions
					in3d); // in 2D		
				greenRoofPoint.setLocalTranslation(0.0f, 25.0f, 0.0f);
				geometry.attachChild(greenRoofPoint);
				
				
			} else if(towerElement.getMaterial() == TowerElement.Material.RED) {
				
				Geometry redRoofWalls = createCylinder(
					40.0f, 20.0f, 20.0f, // Dimensions
					material, // Texture
					246, 150, 54, 80, // Texture position
					80, 40, 80, // Texture dimensions
					in3d); // in 2D
				redRoofWalls.setLocalTranslation(0.0f, 0.0f, 0.1f);
				geometry.attachChild(redRoofWalls);
					
				Geometry redRoofPoint = createCone(
					20.0f, 10.0f, // Dimensions
					material, // Texture
					246, 150, 54, 0, // Texture position
					40, 80, // Texture dimensions
					in3d); // in 2D		
				redRoofPoint.setLocalTranslation(0.0f, 20.0f, 0.0f);
				geometry.attachChild(redRoofPoint);

					
			} else if(towerElement.getMaterial() == TowerElement.Material.BLACK) {
				
				Geometry blackRoofPoint = createCone(
					40.0f, 35.0f, // Dimensions
					material, // Texture
					246, 150, 54, 0, // Texture position
					80, 160, // Texture dimensions
					in3d); // in 2D		
				blackRoofPoint.setLocalTranslation(0.0f, 0.0f, 0.0f);
				geometry.attachChild(blackRoofPoint);
				

			} else if(towerElement.getMaterial() == TowerElement.Material.WHITE) {
				
				Geometry whiteRoofWalls = createCylinder(
					40.0f, 18.0f, 32.0f, // Dimensions
					material, // Texture
					246 + goldenOffset, 150 + goldenOffset, 54 + goldenOffset, 0, // Texture position
					80, 36, 160, // Texture dimensions
					in3d); // in 2D
				whiteRoofWalls.setLocalTranslation(0.0f, 0.0f, 0.1f);
				geometry.attachChild(whiteRoofWalls);
						
				Geometry windowCeiling = createDisc(
					18.0f, // Dimensions
					material, // Texture
					150, 520, // Texture position
					160, // Texture dimensions
					in3d); // in 2D		
				windowCeiling.setLocalTranslation(0.0f, 32.0f, 0.0f);
				geometry.attachChild(windowCeiling);
			}
		}
        
		return geometry;
	}
	
	
	/**
	 * Creates a cylinder where the surfaces are not flipped
	 */
	public static Geometry createCylinder(float diameter1, float diameter2, float height, Material material, float textureCenterOfFace1X, float textureCenterOfFace2X, float textureCenterOfFace3X, float textureY, float textureWidth1, float textureWidth2, float textureHeight, boolean in3D) {
		return createCylinder(diameter1, diameter2, height, material, textureCenterOfFace1X, textureCenterOfFace2X, textureCenterOfFace3X, textureY, textureWidth1, textureWidth2, textureHeight, in3D, false);
	}
	
	/**
	 * Creates a cylinder
	 */
	public static Geometry createCylinder(float diameter1, float diameter2, float height, Material material, float textureCenterOfFace1X, float textureCenterOfFace2X, float textureCenterOfFace3X, float textureY, float textureWidth1, float textureWidth2, float textureHeight, boolean in3D, boolean flipSurface) {
		
		textureWidth1 /= 2.0f;
		textureWidth2 /= 2.0f;
		
		int numberOfFaces = 3;
		
		float[] textureX1 = new float[numberOfFaces * 2];
		float[] textureX2 = new float[numberOfFaces * 2];
		
		textureX1[0] = textureCenterOfFace1X + textureWidth1;
		textureX1[1] = textureCenterOfFace1X - textureWidth1;
		textureX1[2] = textureCenterOfFace2X + textureWidth1;
		textureX1[3] = textureCenterOfFace2X - textureWidth1;
		textureX1[4] = textureCenterOfFace3X + textureWidth1;
		textureX1[5] = textureCenterOfFace3X - textureWidth1;
			
		textureX2[0] = textureCenterOfFace1X + textureWidth2;
		textureX2[1] = textureCenterOfFace1X - textureWidth2;
		textureX2[2] = textureCenterOfFace2X + textureWidth2;
		textureX2[3] = textureCenterOfFace2X - textureWidth2;
		textureX2[4] = textureCenterOfFace3X + textureWidth2;
		textureX2[5] = textureCenterOfFace3X - textureWidth2;
		
		Mesh mesh = new Mesh();
        
        Vector3f[] vertices = new Vector3f[numberOfFaces * 4];
        Vector2f[] textureCoords = new Vector2f[numberOfFaces * 4];
        int[] indexes = new int[numberOfFaces * 6];
        
        for(int i = 0; i < numberOfFaces; i++) {
        	if(in3D) {
        		vertices[(4 * i) + 0] = new Vector3f(hexagonX[i] * diameter2, height, hexagonZ[i] * diameter2);
        		vertices[(4 * i) + 1] = new Vector3f(hexagonX[i] * diameter1,   0.0f, hexagonZ[i] * diameter1);
            
        		vertices[(4 * i) + 2] = new Vector3f(hexagonX[i + 1] * diameter2, height, hexagonZ[i + 1] * diameter2);
        		vertices[(4 * i) + 3] = new Vector3f(hexagonX[i + 1] * diameter1,   0.0f, hexagonZ[i + 1] * diameter1);
        	} else {
        		vertices[(4 * i) + 0] = new Vector3f(hexagonX[i] * diameter2, height + (zScale * hexagonZ[i] * diameter2), 0.0f);
        		vertices[(4 * i) + 1] = new Vector3f(hexagonX[i] * diameter1,   0.0f + (zScale * hexagonZ[i] * diameter1), 0.0f);
            
        		vertices[(4 * i) + 2] = new Vector3f(hexagonX[i + 1] * diameter2, height + (zScale * hexagonZ[i + 1] * diameter2), 0.0f);
        		vertices[(4 * i) + 3] = new Vector3f(hexagonX[i + 1] * diameter1,   0.0f + (zScale * hexagonZ[i + 1] * diameter1), 0.0f);
        	}
        	
            textureCoords[(4 * i) + 0] = new Vector2f(textureX2[(2 * i)] * texRatio, 1.0f - (textureY * texRatio));
            textureCoords[(4 * i) + 1] = new Vector2f(textureX1[(2 * i)] * texRatio, 1.0f - ((textureY + textureHeight) * texRatio));
            
            textureCoords[(4 * i) + 2] = new Vector2f(textureX2[(2 * i) + 1] * texRatio, 1.0f - (textureY * texRatio));
            textureCoords[(4 * i) + 3] = new Vector2f(textureX1[(2 * i) + 1] * texRatio, 1.0f - ((textureY + textureHeight) * texRatio));
            
            if(!flipSurface) {
            	indexes[(6 * i) + 0] = (4 * i) + 2;
                indexes[(6 * i) + 1] = (4 * i) + 3;
                indexes[(6 * i) + 2] = (4 * i) + 1;
                indexes[(6 * i) + 3] = (4 * i) + 1;
                indexes[(6 * i) + 4] = (4 * i) + 0;
                indexes[(6 * i) + 5] = (4 * i) + 2;
            } else {
            	indexes[(6 * i) + 0] = (4 * i) + 2;
                indexes[(6 * i) + 1] = (4 * i) + 1;
                indexes[(6 * i) + 2] = (4 * i) + 3;
                indexes[(6 * i) + 3] = (4 * i) + 1;
                indexes[(6 * i) + 4] = (4 * i) + 2;
                indexes[(6 * i) + 5] = (4 * i) + 0;
            }
        }        
 
        mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
        mesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(textureCoords));
        mesh.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));
 
        Geometry geometry = new Geometry(null, mesh);
        
        geometry.setMaterial(material);
        
        return geometry;
	}
	
	
	/**
	 * Creates a cone
	 */
	public static Geometry createCone(float diameter, float height, Material material, float textureCenterOfFace1X, float textureCenterOfFace2X, float textureCenterOfFace3X, float textureY, float textureWidth, float textureHeight, boolean in3D) {
		
		textureWidth /= 2.0f;
		
		int numberOfFaces = 3;
		
		float[] textureX1 = new float[numberOfFaces * 2];
		float[] textureX2 = new float[numberOfFaces];
		
		textureX1[0] = textureCenterOfFace1X + textureWidth;
		textureX1[1] = textureCenterOfFace1X - textureWidth;
		textureX1[2] = textureCenterOfFace2X + textureWidth;
		textureX1[3] = textureCenterOfFace2X - textureWidth;
		textureX1[4] = textureCenterOfFace3X + textureWidth;
		textureX1[5] = textureCenterOfFace3X - textureWidth;
		
		textureX2[0] = textureCenterOfFace1X;
		textureX2[1] = textureCenterOfFace2X;
		textureX2[2] = textureCenterOfFace3X;
		
		Mesh mesh = new Mesh();
        
        Vector3f[] vertices = new Vector3f[numberOfFaces * 3];
        Vector2f[] textureCoords = new Vector2f[numberOfFaces * 3];
        int[] indexes = new int[numberOfFaces * 3];
        
        for(int i = 0; i < numberOfFaces; i++) {
        	if(in3D) {
        		vertices[(3 * i) + 0] = new Vector3f(0.0f, height, 0.0f);
        		vertices[(3 * i) + 1] = new Vector3f(hexagonX[i] * diameter, 0.0f, hexagonZ[i] * diameter);
        		vertices[(3 * i) + 2] = new Vector3f(hexagonX[i + 1] * diameter, 0.0f, hexagonZ[i + 1] * diameter);
        	} else {
        		vertices[(3 * i) + 0] = new Vector3f(0.0f, height, 0.0f);
        		vertices[(3 * i) + 1] = new Vector3f(hexagonX[i] * diameter, zScale * hexagonZ[i] * diameter, 0.0f);
        		vertices[(3 * i) + 2] = new Vector3f(hexagonX[i + 1] * diameter, zScale * hexagonZ[i + 1] * diameter, 0.0f);
        	}
        	
            textureCoords[(3 * i) + 0] = new Vector2f(textureX2[i] * texRatio, 1.0f - (textureY * texRatio));
            textureCoords[(3 * i) + 1] = new Vector2f(textureX1[(2 * i)] * texRatio, 1.0f - ((textureY + textureHeight) * texRatio));
            textureCoords[(3 * i) + 2] = new Vector2f(textureX1[(2 * i) + 1] * texRatio, 1.0f - ((textureY + textureHeight) * texRatio));        

            indexes[(3 * i) + 0] = (3 * i) + 0;
            indexes[(3 * i) + 1] = (3 * i) + 2;
            indexes[(3 * i) + 2] = (3 * i) + 1;
        }        
 
        mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
        mesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(textureCoords));
        mesh.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));
 
        Geometry geometry = new Geometry(null, mesh);
        
        geometry.setMaterial(material);
        
        return geometry;
	}
	
	
	/**
	 * Creates a disc
	 */
	public static Geometry createDisc(float diameter, Material material, float textureCenterX, float textureCenterY, float textureDiameter, boolean in3D) {
		
		int numberOfFaces = 6;
		
		float[] textureX = new float[numberOfFaces];
		float[] textureY = new float[numberOfFaces];
		
		for(int i = 0; i < numberOfFaces; i++) {
			textureX[i] = textureCenterX + hexagonX[i] * textureDiameter;
			textureY[i] = textureCenterY + hexagonZ[i] * textureDiameter;
		}
		
		Mesh mesh = new Mesh();
        
        Vector3f[] vertices = new Vector3f[numberOfFaces * 3];
        Vector2f[] textureCoords = new Vector2f[numberOfFaces * 3];
        int[] indexes = new int[numberOfFaces * 3];
        
        for(int i = 0; i < numberOfFaces; i++) {
        	if(in3D) {
        		vertices[(3 * i) + 0] = new Vector3f(0.0f, 0.0f, 0.0f);
        		vertices[(3 * i) + 1] = new Vector3f(hexagonX[i] * diameter, 0.0f, hexagonZ[i] * diameter);
        		vertices[(3 * i) + 2] = new Vector3f(hexagonX[i + 1] * diameter, 0.0f, hexagonZ[i + 1] * diameter);
        	} else {
        		vertices[(3 * i) + 0] = new Vector3f(0.0f, 0.0f, 0.0f);
        		vertices[(3 * i) + 1] = new Vector3f(hexagonX[i] * diameter, zScale * hexagonZ[i] * diameter, 0.0f);
        		vertices[(3 * i) + 2] = new Vector3f(hexagonX[i + 1] * diameter, zScale * hexagonZ[i + 1] * diameter, 0.0f);
        	}
        	
            textureCoords[(3 * i) + 0] = new Vector2f(textureCenterX * texRatio, 1.0f - (textureCenterY * texRatio));
            textureCoords[(3 * i) + 1] = new Vector2f(textureX[i % numberOfFaces] * texRatio, 1.0f - (textureY[i % numberOfFaces] * texRatio));
            textureCoords[(3 * i) + 2] = new Vector2f(textureX[(i + 1) % numberOfFaces] * texRatio, 1.0f - (textureY[(i + 1) % numberOfFaces] * texRatio));        

            indexes[(3 * i) + 0] = (3 * i) + 0;
            indexes[(3 * i) + 1] = (3 * i) + 2;
            indexes[(3 * i) + 2] = (3 * i) + 1;
        }        
 
        mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
        mesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(textureCoords));
        mesh.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));
 
        Geometry geometry = new Geometry(null, mesh);
        
        geometry.setMaterial(material);
        
        return geometry;
	}
	
	
	/**
	 * Returns ID of the tower element.
	 */
	public int getId() {
		return towerElement.getId();
	}
	
	
	/**
	 * Returns material of the tower element.
	 */
	public TowerElement.Material getMaterial() {
		return towerElement.getMaterial();
	}
	
	
	/**
	 * Returns true if tower element is golden.
	 */
	public boolean isGolden() {
		return towerElement.isGolden();
	}
	
	
	/**
	 * Returns the height of an element.
	 */
	public static float getHeight(TowerElement element) {
		if(element.getType() == TowerElement.Type.BASE) {
			return 25.0f;
		} else if(element.getType() == TowerElement.Type.MIDDLE) {
			return 15.0f;
		} else if(element.getType() == TowerElement.Type.WINDOW) {
			return 25.0f;
		} else if(element.getType() == TowerElement.Type.ROOF) {
			return 25.0f;
		}
		return 0.0f;
	}


	@Override
	public void update(float delta) {
		timer += delta;
	}


	public GUI.Offset getOffset() {
		return offset;
	}


	public int getPositionX() {
		return positionX;
	}


	public int getPositionY() {
		return positionY;
	}


	public int getzIndex() {
		return zIndex;
	}
	

}
